﻿using HtmlAgilityPack;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace TaobaoMatch
{
    public class Spider
    {
        public static string absUrl = "http://www.taokezhushou.com";

        public static HtmlAgilityPack.HtmlNode GetHtmlNodeFromLink(string url)
        {
            try
            {
                Uri uri = new Uri(url);
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
                request.CookieContainer = new CookieContainer();
                request.UserAgent = "Mozilla/5.0 (compatible;Windows NT 6.1; WOW64;Trident/6.0;MSIE 9.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.27 Safari/537.36";
                request.Proxy = new WebProxy("10.166.17.101", 8080);
                WebResponse response = request.GetResponse();

                Stream stream = response.GetResponseStream();
                StreamReader read = new StreamReader(stream, Encoding.GetEncoding("utf-8"));
                string str = read.ReadToEnd();

                HtmlAgilityPack.HtmlDocument html = new HtmlAgilityPack.HtmlDocument();
                html.LoadHtml(str);
                return html.DocumentNode;
            }
            catch (Exception ex) { return null; }
        }

        public static bool GetGalleryInfo(HtmlAgilityPack.HtmlNode htmlNode, string xPath, ref string[] imgs, ref string[] links, ref string[] title)
        {
            try
            {
                HtmlNodeCollection hnc = htmlNode.SelectNodes(xPath);//"//div[@class='slideBannerA homeSlideAD1']"
                if (hnc.Count < 1)
                    return false;
                links = new string[hnc.Count];
                title = new string[hnc.Count];
                imgs = new string[hnc.Count];
                int i = 0;
                string cateDataRegex = @"background-image:url\((?<image>.+)\)";
                Regex re = new Regex(cateDataRegex, RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.IgnorePatternWhitespace);
                foreach (HtmlNode node in hnc)
                {
                    HtmlAttributeCollection hac = node.Attributes;
                    links[i] = hac["href"].Value;
                    imgs[i] = hac["style"] == null ? hac["src2"].Value : re.Match(hac["style"].Value).Groups["image"].Value;
                    title[i++] = string.IsNullOrEmpty(hac["title"].Value) ? hac["alt"].Value : hac["title"].Value;
                }
                return true;
            }
            catch { return false; }
        }

        public static IDictionary<string, string> ListCate(HtmlAgilityPack.HtmlNode htmlNode, string xPath)
        {
            IDictionary<string, string> dic = new Dictionary<string, string>();
            HtmlNodeCollection hnc = htmlNode.SelectNodes(xPath);//"//div[@class='slideBannerA homeSlideAD1']"
            if (hnc.Count < 1)
                return null;
            int i = 0;
            foreach (HtmlNode node in hnc)
            {
                i++;
                if (i == 1)
                    continue;

                HtmlAttributeCollection hac = node.Attributes;
                dic.Add(GetNumberInt(hac["href"].Value).ToString(), GetChineseWord(node.InnerText));
            }

            return dic;
        }


        public static int GetTotalPages(HtmlAgilityPack.HtmlNode htmlNode, string xPath)
        {
            HtmlNodeCollection hnc = htmlNode.SelectNodes(xPath);//"//div[@class='slideBannerA homeSlideAD1']"
            if (hnc.Count < 1)
                return 0;
            string links = null;
            HtmlNode node = hnc[hnc.Count() - 2];
            links = node.InnerText;
            int total = GetNumberInt(links);
            return total;
        }

        public static IDictionary<string, string> ListCurrentPageUrl(HtmlAgilityPack.HtmlNode htmlNode, string xPath)
        {
            HtmlNodeCollection hnc = htmlNode.SelectNodes(xPath);//"//div[@class='slideBannerA homeSlideAD1']"
            if (hnc.Count < 1)
                return null;
            IDictionary<string, string> links = new Dictionary<string, string>();

            foreach (HtmlNode node in hnc)
            {
                HtmlAttributeCollection hac = node.Attributes;
                links.Add(GetNumberInt(absUrl + hac["href"].Value).ToString(), absUrl + hac["href"].Value);
            }

            return links;
        }

        public static Product GetProduct(HtmlAgilityPack.HtmlNode htmlNode, IDictionary<string, string> DicxPath)
        {
            HtmlNode hncImageUrl = htmlNode.SelectSingleNode(DicxPath["ImageUrl"]);//"//div[@class='slideBannerA homeSlideAD1']"
            HtmlNode hncTitle = htmlNode.SelectSingleNode(DicxPath["Title"]);//"//div[@class='slideBannerA homeSlideAD1']"
            HtmlNode hncCurrentPrice = htmlNode.SelectSingleNode(DicxPath["CurrentPrice"]);//"//div[@class='slideBannerA homeSlideAD1']"
            HtmlNode hncDiscountPrice = htmlNode.SelectSingleNode(DicxPath["DiscountPrice"]);//"//div[@class='slideBannerA homeSlideAD1']"
            HtmlNode hncAfterPrice = htmlNode.SelectSingleNode(DicxPath["AfterPrice"]);//"//div[@class='slideBannerA homeSlideAD1']"
            HtmlNode hncProductDetail = htmlNode.SelectSingleNode(DicxPath["ProductDetail"]);//"//div[@class='slideBannerA homeSlideAD1']"
            HtmlNode hncDiscountUrl = htmlNode.SelectSingleNode(DicxPath["DiscountUrl"]);//"//div[@class='slideBannerA homeSlideAD1']"
            HtmlNode hncDesc = htmlNode.SelectSingleNode(DicxPath["Description"]);//"//div[@class='slideBannerA homeSlideAD1']"
            HtmlNode hncRule = htmlNode.SelectSingleNode(DicxPath["Rule"]);//"//div[@class='slideBannerA homeSlideAD1']"
            HtmlNode hncOther = htmlNode.SelectSingleNode(DicxPath["Other"]);//"//div[@class='slideBannerA homeSlideAD1']"
            HtmlNode hncSaleAmount = htmlNode.SelectSingleNode(DicxPath["SaleAmount"]);//"//div[@class='slideBannerA homeSlideAD1']"
            
            Product p = new Product();
            if (hncImageUrl == null)
                return null;
            p.ImageUrl = hncImageUrl.Attributes["src"].Value;
            p.Title = hncTitle.InnerText;
            p.CurrentPrice = GetNumberDouble(hncCurrentPrice.InnerText);
            p.DiscountPrice = double.Parse(hncDiscountPrice.InnerText);
            p.SaleAmount = GetNumberInt(hncSaleAmount.InnerText);
            p.AfterPrice = double.Parse(hncAfterPrice.InnerText);
            p.ProductDetail = hncProductDetail.Attributes["href"].Value;
            p.DiscountUrl = hncDiscountUrl.Attributes["href"].Value;
            p.LocalImageUrl = AppConfig.UploadFilePath + p.Title + DateTime.Now.ToString("yyyyMMddHHmmss") + ".jpg";
            p.CreateTime = DateTime.Now;
            p.Description = hncDesc.InnerText;
            p.Rule = hncRule.InnerText;
            string other = hncOther.InnerHtml;
            try
            {
                string surplusAmount = other.Substring(other.IndexOf("span") + 5);
                p.SurplusAmount = int.Parse(surplusAmount.Substring(0, surplusAmount.IndexOf("span") - 2));
                string used = other.Substring(other.IndexOf("已领券") + 3);
                p.UsedAmount = int.Parse(used.Substring(0, used.LastIndexOf("张")));
                p.ExpiredTime = DateTime.Parse(other.Substring(other.IndexOf("过期时间") + 4));
                p.TotalAmount = p.SurplusAmount + p.UsedAmount;
            }
            catch (Exception ex)
            {

            }
            SavePic(p.ImageUrl, p.LocalImageUrl);
            return p;
        }

        public static string GetPageUrl(int i)
        {
            return "http://www.taokezhushou.com?page=" + i + "#new";
        }

        public static string GetPageUrlForCate(int page, string cate)
        {
            return "http://www.taokezhushou.com/cate/" + cate + "?page=" + page + "#new";
        }

        #region private

        private static int GetNumberInt(string str)
        {
            int result = 0;
            if (str != null && str != string.Empty)
            {
                str = Regex.Replace(str, @"[^\d\d]", "");

                if (Regex.IsMatch(str, @"\d*[.]?\d*$"))
                {
                    result = int.Parse(str);
                }

            }

            return result;

        }

        private static double GetNumberDouble(string str)
        {
            double result = 0;
            if (str != null && str != string.Empty)
            {
                str = Regex.Replace(str, @"[^\d.\d]", "");

                if (Regex.IsMatch(str, @"\d*[.]?\d*$"))
                {
                    result = double.Parse(str);
                }
            }

            return result;
        }

        private static string GetChineseWord(string oriText)
        {

            string x = @"[\u4E00-\u9FFF]+";
            MatchCollection Matches = Regex.Matches
            (oriText, x, RegexOptions.IgnoreCase);
            StringBuilder sb = new StringBuilder();
            foreach (Match NextMatch in Matches)
            {
                sb.Append(NextMatch.Value);
            }
            return sb.ToString();
        }

        private static void SavePic(string url, string name)
        {
            WebClient client = new WebClient();
            client.Proxy = new WebProxy("10.166.17.101", 8080);

            byte[] bytes = client.DownloadData(new Uri(url));

            MemoryStream ms = new MemoryStream(bytes);
            ms.Seek(0, SeekOrigin.Begin);
            ms.WriteTo(new FileStream(name, FileMode.OpenOrCreate));
        }

        #endregion

    }
}
